package com.seeyon.apps.bense.bank.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import www.seeyon.com.utils.DateUtil;

import com.alibaba.druid.util.StringUtils;
import com.seeyon.apps.bense.bank.core.Constants;
import com.seeyon.apps.bense.bank.core.OpenSDKClient;
import com.seeyon.apps.bense.bank.enums.BankAPIEnum;
import com.seeyon.apps.bense.common.domain.Cap4Update;
import com.seeyon.apps.bense.common.domain.Cap4Where;
import com.seeyon.apps.bense.common.manager.CAP4FormDataManagerExt;
import com.seeyon.apps.bense.util.CAP4FormKit;
import com.seeyon.apps.collaboration.manager.ColManager;
import com.seeyon.apps.collaboration.po.ColSummary;
import com.seeyon.apps.common.utils.CAP4FormFieldUtils;
import com.seeyon.apps.econtract.platform.params.output.TemplateListOutput.Data.list;
import com.seeyon.apps.ningbobank.manager.NingBoBankSuperNodeManager;
import com.seeyon.apps.u8cloud.manager.U8CloudApiManager;
import com.seeyon.apps.u8cloud.manager.U8CloudVoucherManager;
import com.seeyon.apps.u8cloud.manager.VoucherRecordManager;
import com.seeyon.apps.u8cloud.model.Details;
import com.seeyon.apps.u8cloud.model.ParamAss;
import com.seeyon.apps.u8cloud.model.ResultData;
import com.seeyon.apps.u8cloud.model.Voucher;
import com.seeyon.apps.u8cloud.model.VoucherParams;
import com.seeyon.apps.u8cloud.model.VoucherRecord;
import com.seeyon.apps.u8cloud.model.VoucherResult;
import com.seeyon.cap4.form.bean.FormBean;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import com.seeyon.cap4.form.bean.FormFieldBean;
import com.seeyon.cap4.form.service.CAP4FormManager;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.affair.strategy.newsStrategy;
import com.seeyon.ctp.common.constants.ApplicationCategoryEnum;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.common.filemanager.manager.AttachmentManager;
import com.seeyon.ctp.common.filemanager.manager.FileManager;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.common.po.filemanager.V3XFile;
import com.seeyon.ctp.util.FlipInfo;
import com.seeyon.ctp.util.ParamUtil;
import com.seeyon.ctp.util.UUIDLong;
import com.seeyon.ctp.util.annotation.Inject;
import com.seeyon.ctp.util.concurrent.ExecutorServiceFactory;
import com.seeyon.ctp.util.json.JSONUtil;
import com.seeyon.ctp.workflow.supernode.enums.SuperNodeEnums;

import org.opensaml.saml2.core.NewID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;

public class ZongZhangPayManagerImpl {

    private static final Logger log = LoggerFactory.getLogger(ZongZhangPayManagerImpl.class);

    private static CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");

    private CAP4FormDataManagerExt cap4FormDataManagerExt = (CAP4FormDataManagerExt) AppContext.getBean("cap4FormDataManagerExt");

    private OpenSDKClient openSDKClient = (OpenSDKClient) AppContext.getBean("openSDKClient");

    private ColManager colManager;
    
    private static String serviceUrl = AppContext.getSystemProperty("u8cloud.serviceUrl");
    
    @Inject
    private U8CloudApiManager u8CloudApiManager;
    @Inject
    private U8CloudVoucherManager u8CloudVoucherManager;
    @Inject
    private VoucherRecordManager voucherRecordManager;
    /**
     * 定时查询付款回执结果接口
     *
     * @throws Exception
     */
    public void doSync() {
        FormBean formBean = null;
        try {
            formBean = cap4FormManager.getFormByFormCode(Constants.bankAccTab);
        } catch (BusinessException e) {
            log.error("模板编号: 【{}】 查询表单失败", Constants.bankAccTab, e);
        }
        Assert.notNull(formBean, "银行账号配置表未配置模板编号");

        //根据工号查询底表里是否存在，存在则跳过，否则新增
//        FormFieldBean fieldBean = CAP4FormKit.getFieldBean(formBean.getMasterTableBean(), "回执状态");
//        Assert.notNull(fieldBean, "表单【{}】,字段【{}】定义不存在", formBean.getFormName(), "回执状态");
        Cap4Where masterWhere = new Cap4Where();
        int page = 1;
        List<FormDataMasterBean> masterExists = cap4FormDataManagerExt.selectMasterDataList(new FlipInfo(page, 200), formBean, null, masterWhere);
        if (CollectionUtil.isEmpty(masterExists)) {
            log.info("***********银行账号配置表【表单编号{}】没有数据***********", Constants.travelPaymentTab);
            return;
        }

//       税务账：
//           手续费---
//         		借方：手续费支出（6421）无辅助核算，
//              贷：银行存款-基本户（100201）/一般户（100202）（和报销单一样，银行账户辅助核算）；
//          利息收入---
//              借方：银行存款-基本户（100201）/一般户（100202）（和报销单一样，银行账户辅助核算），
//              贷：利息收入（6011）无辅助核算
        
//        总账：手
//        	续费---
//        		借方：手续费支出（6421）无辅助核算，
//        		贷：银行存款-二级三级科目，无辅助核算（和总账的银行一样）；
//        	利息收入---
//        		借方：银行存款-二级三级科目，无辅助核算（和总账的银行一样），
//        		贷：利息收入（6011）无辅助核算
        while (CollectionUtil.isNotEmpty(masterExists)) {
        	Map<String, Object> paramMap = new HashMap<>();
            for (int i = 0, len = masterExists.size(); i < len; i++) {
                FormDataMasterBean formDataMasterBean = masterExists.get(i);
                String bankAcc = CAP4FormKit.getFieldStrValue(formDataMasterBean, "银行账号");
                List<String> bankAccList = new ArrayList<String>();
                bankAccList.add("40010122000156763");
                paramMap.put("bankAccList", bankAccList);
            
	            paramMap.put("custId", Constants.custId);//必须为财资系统十位集团客户号
	            paramMap.put("queryType", "0");//查询方式  0：分页查询1：下载文件查询
	            paramMap.put("pageSize", "1000");//必须为财资系统十位集团客户号
	            paramMap.put("currentPage", "1");//当前页数
				paramMap.put("beginDate","2025-04-01");
				paramMap.put("endDate","2025-04-30");
	            //交易明细查询
	            Map<String, Object> dataMap = getData(BankAPIEnum.GET_QueryAccDetail_URL, paramMap);

	            //0000：成功    0001：失败
	            if ("0000".equals(MapUtil.getStr(dataMap, "retCode"))) {
	            	BigDecimal amtTotle = BigDecimal.ZERO;
	            	String pageSize = MapUtil.getStr(dataMap, "pageSize");
	            	String totalSize = MapUtil.getStr(dataMap, "totalSize");
	            	List<Map<String, Object>> list = MapUtil.get(dataMap, "list", List.class);
					log.info("银行明细调用list结果："+list);
	            	 if (CollectionUtil.isNotEmpty(list)) {
	                    for (int j = 0; j < list.size(); j++) {
	                    	//对方账号
	                    	String oppAccNo = MapUtil.get(list.get(j), "oppAccNo", String.class);
	                    	//摘要
	                    	String abs = MapUtil.get(list.get(j), "abs", String.class);
							log.info("银行明细调用摘要结果："+abs);
	                    	//交易金额
	                    	String amt = MapUtil.get(list.get(j), "amt", String.class);
	                    	if("公共缴费".equals(abs) ||"批量扣费".equals(abs) || StrUtil.isBlank(oppAccNo)) {
	                    		//说明是手续费 、利息 、年费、服务费--目标对象
	                    		amtTotle = amtTotle.add(new BigDecimal(amt));
	                    	}
						}
	                 }
	            	 
	            	 //生成对应的凭证
	            	 VoucherParams voucherParams = getPaymentVoucherParams(formDataMasterBean,amtTotle);
	                 VoucherResult voucherResult = u8CloudApiManager.createVoucher(voucherParams);
	                 if (voucherResult.getStatus().equals("success")) {
	                     List<ResultData> resultData = voucherResult.getResultData();
	                     //凭证号no
	                     String pkVoucher = resultData.get(0).getNo();
	                 } 
	                 
	                 VoucherRecord voucherRecord = new VoucherRecord();
	                 voucherRecord.setDataId(UUID.randomUUID().toString());
	                 voucherRecord.setFormId(formBean.getId().toString());
	                 voucherRecord.setSubject("手续费 、年费、服务费");
	                 if (voucherResult.getStatus().equals("success")) {
	                     voucherRecord.setVoucherId(voucherResult.getResultData().get(0).getPk_voucher());
	                     voucherRecord.setVoucherCode(voucherResult.getResultData().get(0).getNo());
	                 }
	                 voucherRecord.setStatus(voucherResult.getStatus());
	                 voucherRecord.setServiceUrl(serviceUrl + "/u8cloud/api/gl/voucher/insert");
	                 voucherRecord.setParams(JSONUtil.toJSONString(voucherParams));
	                 voucherRecord.setResult(JSONUtil.toJSONString(voucherResult));
	                 voucherRecord.setCreateDate(DateUtil.get19DateAndTime());
	                 ExecutorServiceFactory.getDefaultThreadPool().submit(new Runnable() {
	                     @Override
	                     public void run() {
	                         try {
	                             voucherRecordManager.saveDockingRecords(voucherRecord);
	                         } catch (Exception e) {
	                             log.error("保存对接日志异常：", e);
	                         }
	                     }
	                 });
	            }
            }
        }
    }

    private Map<String, Object> getData(BankAPIEnum bankAPIEnum, Map<String, Object> paramMap) {
        Map<String, Object> result = openSDKClient.sendRequest(bankAPIEnum.url(), paramMap);
        Map<String, Object> dataMap = MapUtil.get(result, "Data", Map.class);
        return dataMap;
    }

	/**
	 * @param master 
	 * @param amtTotle 
	 * @MethodName: getPaymentVoucherParams
	 * @Description: 获取付款凭证参数
	 * @CreateDate: 2025/9/2 14:09
	 * @Author: CheungHowrAn
	 * @Param master
	 * @Param formBean
	 * @Return List<Details>
	 */
	public VoucherParams getPaymentVoucherParams(FormDataMasterBean master, BigDecimal amtTotle) {
		VoucherParams voucherParams = new VoucherParams();
		try {
			List<Voucher> vouchers = new ArrayList<>();
			Voucher voucher = new Voucher();
			// 摘要信息 3.12付款事由
			voucher.setExplanation("手续费 、利息 、年费、服务费等自动扣款");
			// 传业务发生具体公司（业务单元/组织）编码 todo 字段确认
			String pkCorp = CAP4FormFieldUtils.getFormFieldVal(master, "公司编码",
					CAP4FormFieldUtils.FormFieldValType.SHOW_CODE);
			log.info("公司编码:" + pkCorp);
			voucher.setPk_corp(pkCorp);
			// 传业务发生具体公司（业务单元/组织）账簿编码 todo 字段确认
			String accountBook = CAP4FormFieldUtils.getFormFieldVal(master, "账簿编码",
					CAP4FormFieldUtils.FormFieldValType.SHOW_NAME);
			log.info("账簿信息:" + accountBook);
			voucher.setPk_glorgbook(accountBook);
			// 制单人（对应u8c用户档案的用户编码） todo 字段确认
			String prepared = CAP4FormFieldUtils.getFormFieldVal(master, "负责人",
					CAP4FormFieldUtils.FormFieldValType.SHOW_CODE);
			log.info("负责人:" + prepared);
			voucher.setPk_prepared(prepared);

			String preparedDate = DateUtil.getDate();
			log.info("本月末日期:" + preparedDate);
			voucher.setPrepareddate(preparedDate);

			Integer detailIndex = 1;
			// 凭证明细
			List<Details> detailsList = new ArrayList<>();

			// 借：库存商品 借方科目
			Details inventoryGoodsDetails = new Details();
			// 原币贷方金额
			inventoryGoodsDetails.setCreditamount("0");
			// 如果没有外币业务情况可以跟creditamount传输一样值
			inventoryGoodsDetails.setLocalcreditamount("0");
			// 原币借方金额
			inventoryGoodsDetails.setDebitamount(amtTotle.toString());
			// 如果没有外币业务情况可以传debitamount一样
			inventoryGoodsDetails.setLocaldebitamount(amtTotle.toString());
			// 分录行也可以理解为行号从1开始排
			inventoryGoodsDetails.setDetailindex(detailIndex.toString());
			inventoryGoodsDetails.setExplanation("手续费 、利息 、年费、服务费等自动扣款");
			//借方科目
			inventoryGoodsDetails.setPk_accsubj(CAP4FormFieldUtils.getFormFieldVal(master, "税务销售科目编码-借",
					CAP4FormFieldUtils.FormFieldValType.SHOW_NAME));

			// 辅助科目*********用的是自定义字段--"门店"
//			ParamAss ass = new ParamAss();
//			ass.setChecktypecode("73");// 73 客商辅助核算
//			ass.setCheckvaluecode(CAP4FormFieldUtils.getFormFieldVal(master, "收款单位编码",
//					CAP4FormFieldUtils.FormFieldValType.SHOW_NAME));
//			List<ParamAss> assList = new ArrayList<>();
//			assList.add(ass);
//			inventoryGoodsDetails.setAss(assList);

			detailsList.add(inventoryGoodsDetails);
			detailIndex++;

			// 贷：银行存款 贷方金额
			Details bankDepositDetails = new Details();
			// 原币贷方金额
			bankDepositDetails.setCreditamount(amtTotle.toString());
			// 如果没有外币业务情况可以跟creditamount传输一样值
			bankDepositDetails.setLocalcreditamount(amtTotle.toString());
			// 原币借方金额
			bankDepositDetails.setDebitamount("0");
			// 如果没有外币业务情况可以传debitamount一样
			bankDepositDetails.setLocaldebitamount("0");
			// 分录行也可以理解为行号从1开始排
			bankDepositDetails.setDetailindex(detailIndex.toString());
			// 摘要信息
			bankDepositDetails.setExplanation("手续费 、利息 、年费、服务费等自动扣款");
			// 科目代码
			bankDepositDetails.setPk_accsubj(CAP4FormFieldUtils.getFormFieldVal(master, "贷方科目编码",
					CAP4FormFieldUtils.FormFieldValType.SHOW_NAME));
			// 辅助科目*********
			ParamAss bankDepositAss = new ParamAss();
			bankDepositAss.setChecktypecode("96");// 银行
			bankDepositAss.setCheckvaluecode(CAP4FormFieldUtils.getFormFieldVal(master, "付款银行账号",
					CAP4FormFieldUtils.FormFieldValType.SHOW_NAME));
			List<ParamAss> bankDepositAssList = new ArrayList<>();
			bankDepositAssList.add(bankDepositAss);
			bankDepositDetails.setAss(bankDepositAssList);
		
			detailsList.add(bankDepositDetails);
			detailIndex++;

			voucher.setDetails(detailsList);
			vouchers.add(voucher);
			voucherParams.setVoucher(vouchers);
		} catch (Exception e) {
			log.error("付款凭证生成事件异常", e);
		}
		return voucherParams;
	}
}
